package com.xb.loan.fund.task;

import com.xb.loan.cashier.service.IEncashOrderService;
import com.xb.loan.cashier.service.bean.CashierEncashBO;
import com.xb.loan.encryptor.crypt.Encryptor;
import com.xb.loan.encryptor.crypt.EncryptorManager;
import com.xb.loan.fund.service.ICashEncashService;
import com.xb.loan.fund.service.ICashVerifyErrorService;
import com.xb.loan.fund.service.bean.CashEncashVO;
import com.xb.loan.fund.service.bean.CashVerifyErrorVO;
import com.xb.loan.fund.service.constant.FundConst;
import com.xb.loan.log.exception.BizException;
import com.xb.loan.util.cache.redis.comm.FormatOperation;
import com.xb.loan.util.log.LogFormatUtil;
import com.xb.loan.util.qrtz.task.AbstractCronTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**提现发给收银台任务
 */

public class CashEncashTask extends AbstractCronTask {

    private Logger logger = LoggerFactory.getLogger(CashEncashTask.class);
    
 
    private ICashEncashService cashEncashService;
    

    private IEncashOrderService cashierEncashService;
    

    private ICashVerifyErrorService cashVerifyErrorService;
    
    // 加密算法
    Encryptor _encrytor = EncryptorManager.getEncryptor("user");
    
 // 加密算法（用于与收银台通讯）
    Encryptor partnerEncrytor = EncryptorManager.getEncryptor("partner");
    
    @Override
    public void run() {  
        logger.info(LogFormatUtil.getFormatMsg(new String[]{"module", "msg"},
        		new Object[]{"cashEncash.submit", "start."}));
        try{
        	initTask();
            handleCashEncash();
            logger.info(LogFormatUtil.getFormatMsg(new String[]{"module", "msg"},
        			new Object[]{"cashEncash.submit", "end."}));
        }catch(BizException e){
        	logger.error(LogFormatUtil.getFormatMsg(new String[]{"module", "msg"},
        			new Object[]{"cashEncash.submit", "error."}), e);
        }
        
    }
    
    /**
     * 初始化参数
     *
     * @author zheng.p
     * @version 2015年9月14日
     */
    private void initTask() {
        //初始化参数
        this.cashEncashService = getSpringBean("cashEncashService");
        this.cashierEncashService = getSpringBean("cashierEncashService");
        this.cashVerifyErrorService = getSpringBean("cashVerifyErrorService");
    }
    
    /**
     * 线程启动后处理开始
     * 2015年9月13日 by wuqinglong
     */
    private void handleCashEncash()  throws BizException{
        //查询待处理的提现记录，一次20条
        List<CashEncashVO> list = cashEncashService.queryCashEncash(null, FundConst.EncashStatus_Wait, null, null, 1, 20);
        
        while(list !=null && list.size() > 0){
        	
        	logger.info(LogFormatUtil.getFormatMsg(new String[]{"module", "msg"},
        			new Object[]{"cashEncash.submit", list.size() + " records need to submit."}));
        	
            for(CashEncashVO cashEncashVO:list){
                if(!verifyLocalDate(cashEncashVO))
                    continue;
                
                CashierEncashBO cashierEncashBO = getCashierEncashVO(cashEncashVO);
                cashierEncashService.encash(cashierEncashBO);
                cashEncashService.submitCashEncash(cashEncashVO.getEncashId());
            }
            //查询是否还有待处理的提现记录
            list = cashEncashService.queryCashEncash(null, null, FundConst.EncashStatus_Wait, null, null, 1, 20);
        }
    }
    
    private boolean verifyLocalDate(CashEncashVO cashEncashVO) throws BizException{
        // 使用“user模式”验证本地提现信息数据是否被篡改。
        if(!_encrytor.encryptValidate(cashEncashVO.getUserId(), cashEncashVO.getEncashId(), cashEncashVO.generateKey(), cashEncashVO.getDigitalSign())){
            logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "encashId", "msg"},
            		new Object[]{"cashEncash.submit", cashEncashVO.getEncashId(), "本地验签失败"}));
            // 将订单更新为失败，以免再次取出
            cashEncashService.deleteEncashOrder(cashEncashVO.getEncashId());
            // 添加验签错误记录
        	CashVerifyErrorVO verifyErrorVO = addVerifyError(cashEncashVO);
            cashVerifyErrorService.addCashVerifyError(verifyErrorVO);
            
            return false;
        }
        return true;
    }
    
    /**
     * 生成错误日志
     * @param cashEncash
     * @return
     * 2015年9月15日 by wuqinglong
     */
    private CashVerifyErrorVO addVerifyError(CashEncashVO cashEncashVO){
        CashVerifyErrorVO ve=new CashVerifyErrorVO();
        String fundLimitId= FormatOperation.assemblySeq(FundConst.PriKey_Name, FundConst.PriKey_Length);
        ve.setFundLimitId(fundLimitId);
        ve.setUserId(cashEncashVO.getUserId());
        ve.setPlatId(cashEncashVO.getPlatId());
        ve.setPartnerId(cashEncashVO.getPartnerId());
        ve.setMoney(cashEncashVO.getMoney());
        ve.setAccountName(cashEncashVO.getCardName());
        ve.setAccountNo(cashEncashVO.getCardNo());
        ve.setDigitalSign(cashEncashVO.getDigitalSign());
        ve.setOrderId(cashEncashVO.getEncashId());
        ve.setErrorType(FundConst.VerifyErrorType_LOCALERROR);
        ve.setOrderType(FundConst.FundType_Encash);
        ve.setStatus(FundConst.VerifyErrorStatus_Wait);
        return ve;
    }
    
    
   /**
    * 根据提现记录生成收银台提现任务VO
    * @param cashEncash     提现记录
    * @return               返回收银台提现任务VO
    * 2015年9月13日 by wuqinglong
    */
   private CashierEncashBO getCashierEncashVO(CashEncashVO cashEncashVO){
	   CashierEncashBO cashierEncashBO=new CashierEncashBO();
        cashierEncashBO.setUserId(cashEncashVO.getUserId());
        cashierEncashBO.setOrderId(cashEncashVO.getEncashId());
        cashierEncashBO.setPlatId(cashEncashVO.getPlatId());
        cashierEncashBO.setPartnerId(cashEncashVO.getPartnerId());
        cashierEncashBO.setMoney(cashEncashVO.getMoney());
        cashierEncashBO.setAccountPeriod(cashEncashVO.getAccountPeriod());
        cashierEncashBO.setSellName(cashEncashVO.getCardName());
        cashierEncashBO.setSellAccount(cashEncashVO.getCardNo());
        cashierEncashBO.setSellBank(cashEncashVO.getBankCode() + "");   
        //生成加密码信息
        String sign = partnerEncrytor.encrypt(FundConst.Cashier_Cert, null, cashEncashVO.generateKey());
        cashierEncashBO.setSign(sign);
        
        return cashierEncashBO;
    }
}
